import {
	_decorator,
	assetManager,
	AssetManager,
	Component,
	instantiate,
	Node,
	Prefab,
	TextAsset,
	v3,
} from 'cc'
import { ExcelMgr } from './ExcelMgr'
import { FruitItem } from './FruitItem'
const { ccclass, property } = _decorator

interface Fragment {
	ID: string
	difficulty: string
	forceX: string
	forceY: string
	fruitId: string
	positionX: string
	time: string
}

export interface FruitConfig {
	ID: string
	name: string
	type: string
	prefab: string
	color: string
	trailScale: string
	trailPath: string
	scale: string
	particleScale: string
}

enum GameState {
	Ready = 1,
	Running = 2,
	Checkout = 3,
}

@ccclass('GameMgr')
export class GameMgr extends Component {
	private excelBundle: AssetManager.Bundle = null // Excel表格对应的bundle资源包
	private fruitBundle: AssetManager.Bundle = null // 水果对应的bundle资源包(ab包)
	private difficulty: number = 1 // 游戏难度，从1到5不断递增，到5以后循环5
	private fragments: Fragment[] = [] // 当前难度的等级数组
	private fragIndex: number = 0 // 当前等级的索引
	private allFragments: Fragment[] = [] // 所有难度等级的数组
	private passedTime: number = 0 // 从开始生成水果过去的时间
	private nextTime: number = 0 // 下一次生成水果的时间
	private gameState: GameState = GameState.Ready

	private fruitRoot: Node = null // 水果预制体根节点
	private spawnLine: number = -10 // 生成水果Y轴位置

	start() {
		this.fruitRoot = this.node.getChildByName('fruitRoot')
		this.node.addComponent(ExcelMgr)
		this.preloadGameAssetBundles()
	}

	update(deltaTime: number) {
		this.genFruitUpdate(deltaTime)
	}

	private preloadGameAssetBundles(): void {
		assetManager.loadBundle('Datas', (err: any, bundle: AssetManager.Bundle) => {
			if (err) {
				console.error(err)
				return
			}
			this.excelBundle = bundle

			assetManager.loadBundle('FruitModels', (err: any, bundle: AssetManager.Bundle) => {
				if (err) {
					console.error(err)
					return
				}
				this.fruitBundle = bundle

				this.preloadGameAssets()
			})
		})
	}

	private preloadGameAssets(): void {
		if (this.excelBundle === null || this.fruitBundle === null) {
			console.error('load game asset error !!!')
			return
		}

		this.excelBundle.loadDir('./', TextAsset, () => {
			this.fruitBundle.loadDir('./', Prefab, () => {
				this.EnterGame()
			})
		})
	}

	private getFragmentByDifficulty(difficulty: number): Fragment[] {
		const fragments = []
		this.allFragments.forEach((item) => {
			if (Number(item.difficulty) === difficulty) {
				fragments.push(item)
			}
		})
		return fragments
	}

	private EnterGame(): void {
		// 获取excel资源
		// const textAsset: TextAsset = this.excelBundle.get('fragment')
		// console.log(textAsset.text, 44)

		// 获取预制体资源
		// const apple: Prefab = this.fruitBundle.get('apple')
		// console.log(apple, 47)

		// 加载excel表格数据
		ExcelMgr.Instance.addTable('fragment', (this.excelBundle.get('fragment') as TextAsset).text)
		ExcelMgr.Instance.addTable('fruit', (this.excelBundle.get('fruit') as TextAsset).text)

		// 获取单个水果数据数据
		// const fruitConfig = ExcelMgr.Instance.queryByID('fruit', '1003')
		// console.log(fruitConfig, 54)

		this.allFragments = ExcelMgr.Instance.getTableArr('fragment')
		this.gameState = GameState.Ready
		this.resetGame()
	}

	private genOneFruit(): void {
		// 根据配置表中的一条内容产生水果
		const fragConfig = this.fragments[this.fragIndex]
		this.genFruitNodeWithConfig(fragConfig)

		// 进入下一个的计时
		this.passedTime = 0
		this.nextTime = Number(fragConfig.time)
		this.fragIndex++
		// 如果当前难度数组已经结束，则进入下一个难度
		if (this.fragIndex >= this.fragments.length) {
			this.difficulty++
			const fragments = this.getFragmentByDifficulty(this.difficulty)
			if (fragments.length <= 0) {
				// 如果已经跑完了所有难度数组，则继续跑难度等级为5的数组
				this.difficulty--
			} else {
				// 否则进入下一个难度
				this.fragments = fragments
			}
			this.fragIndex = 0
		}
	}

	public resetGame(): void {
		this.fruitRoot.removeAllChildren()
		this.difficulty = 1
		this.fragments = this.getFragmentByDifficulty(this.difficulty)
		if (this.fragments.length <= 0) {
			console.error('error,check config data !!!')
			return
		}
		this.fragIndex = 0 // 从当前难度的第一个开始
		this.gameState = GameState.Running
		this.genOneFruit()
	}

	private genFruitUpdate(deltaTime: number) {
		if (this.gameState !== GameState.Running) return

		this.passedTime += deltaTime
		if (this.passedTime >= this.nextTime) {
			this.passedTime = 0
			this.genOneFruit()
		}
	}

	private genFruitNodeWithConfig(fragConfig: Fragment): void {
		// 根据fragConfig找到到底是哪个水果（根据id,-1为随机水果,1008为炸弹）
		const fruitId = fragConfig.fruitId
		let fruitConfig: FruitConfig = null

		if (fruitId === '-1') {
			// s随机水果
			const fruitConfigs = ExcelMgr.Instance.getTableArr('fruit')
			const totalCount = fruitConfigs.length
			const randomIndex = Math.floor(Math.random() * totalCount)
			fruitConfig = fruitConfigs[randomIndex]
		} else {
			// 炸弹

			fruitConfig = ExcelMgr.Instance.queryByID('fruit', fruitId)
		}
		const fruitPrefab: Prefab = this.fruitBundle.get(fruitConfig.prefab)
		const fruitNode: Node = instantiate(fruitPrefab)
		this.fruitRoot.addChild(fruitNode)
		// 设置节点的位置
		const per: number = Number(fragConfig.positionX) / 1280
		const totalLen = 18 // 整个背景的长度
		const pos_x = -totalLen * 0.5 + per * totalLen
		const pos_y = this.spawnLine // 水果出生的高度
		const pos_z = -10 // 背景距离摄像机的距离
		fruitNode.setPosition(pos_x, pos_y, pos_z)

		// 实例化水果控制逻辑
		const fruitItem: FruitItem = fruitNode.addComponent(FruitItem)
		fruitItem.initFruit(fruitConfig)
		const fx = parseFloat(fragConfig.forceX)
		const fy = parseFloat(fragConfig.forceY)
		fruitItem.throwFruitOut(v3(fx, fy, 0))
	}
}
